iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 10
0
自我挑戰組

Tensorflow.js初學筆記系列 第 10

Day9 TensorFlow.js: MNIST手寫數字辨識

  • 分享至 

  • xImage
  •  

Day9 TensorFlow.js: MNIST 手寫數字辨識
昨天基本上針對最簡單的回歸問題求解
熟悉一下TensorFlow的處理流程
1.準備模型(定義神經網路層->設定最佳化方法與損失計算方法)
2.拿到資料,對資料轉成tensor並正規化
3.訓練模型
4.使用模型
順便把結果視覺化出來。

今天就是開始學習辨識
機器學習領域的Hello World! ->MNIST手寫數字資料辨識
MNIST的資料官網

下載與之相對的資料處理js檔
記得刪掉import跟export 只要依順序載入檔案就行

然後跟昨天一樣來準備個模型

function createModel() {
    const model = tf.sequential();

    const IMAGE_WIDTH = 28;
    const IMAGE_HEIGHT = 28;
    const IMAGE_CHANNELS = 1;

    //新增卷積層
    model.add(tf.layers.conv2d({
        inputShape: [IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS],
        kernelSize: 5,
        filters: 8,
        strides: 1,
        activation: 'relu',
        kernelInitializer: 'varianceScaling'
    }));

    //池化層 
    model.add(tf.layers.maxPooling2d({
        poolSize: [2, 2],
        strides: [2, 2]
    }));

    //重複一個卷積層一個池化層
    model.add(tf.layers.conv2d({
        kernelSize: 5,
        filters: 16,
        strides: 1,
        activation: 'relu',
        kernelInitializer: 'varianceScaling'
    }));
    model.add(tf.layers.maxPooling2d({
        poolSize: [2, 2],
        strides: [2, 2]
    }));

    // 扁平層轉化剛剛的二維資訊變成一維,好讓1-10被辨識出來
    model.add(tf.layers.flatten());

    // 最後出來得結果要是0-9共10個答案
    model.add(tf.layers.dense({
        units: 10,
        kernelInitializer: 'varianceScaling',
        activation: 'softmax'
    }));

    // 定義損失函數
    model.compile({
        optimizer: tf.train.adam(),
        loss: 'categoricalCrossentropy',
        metrics: ['accuracy'],
    });

    return model;
}

有關這個模型為什麼是長這樣,就必須先了解CNN(Convolutional Neural Network卷積神經網路)
先看看CNN的結構圖

取自A Comprehensive Guide to Convolutional Neural Networks — the ELI5 way
中間又必須了解NN的運作的理解,
不過我還沒想得很清楚怎麼表達(畫圖實在太累了)
先跳過那部分的筆記,等到之後再來補
這邊是因為不講清楚CNN,以後看這裡會看不懂

首先是卷積層
取固定大小內的像素(也就是上面定義的kernelSize)
透過一個特徵選取矩陣決定這個矩陣哪些像素要加強,那些像素要降低
像做邊緣檢測一樣.....(想到之前修平行的時候,做影像處理,真的搞很久才懂)

右下角是各自的特徵選取矩陣(kernelSize=3)
在整個卷積層中,會隨機產生多個不同的特徵選取矩陣(也就是上面定義的filters)
stride表示取完一橫排後
會像下幾格取下一個橫排
所以會看到卷積層內會產生多張被處理過後的圖
並透過ReLU去掉可能算出的像素值是負的部分

池化層,其實可以把它想像成馬賽克
取固定大小內的像素(poolSize)
通通用一個數字表達,取最大、平均.....
stride表示取完一個向右2格
取完一橫排會像下2格取下一個橫排
簡單來說,就是會簡化卷積層上的特徵圖,讓之後計算方便一點,也可以讓其對每個像素敏感度不要那麼高。

取自cs231n.github

今天花很多時間在了解CNN,沒什麼時間完成整個部分,明天再補


上一篇
Day8 初探TensorFlow.js,不用設定環境的機器學習
下一篇
Day10 TensorFlow.js: MNIST手寫數字辨識2
系列文
Tensorflow.js初學筆記27
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言